home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: Joystick.cpp
- //
- // Desc: Demonstrates an application which receives immediate
- // joystick data in exclusive mode via a dialog timer.
- //
- // Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #define STRICT
- #include <windows.h>
- #include <basetsd.h>
- #include <dinput.h>
- #include "resource.h"
-
-
-
-
- //-----------------------------------------------------------------------------
- // Function-prototypes
- //-----------------------------------------------------------------------------
- INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
- BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
- BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );
- HRESULT InitDirectInput( HWND hDlg );
- VOID FreeDirectInput();
- HRESULT UpdateInputState( HWND hDlg );
-
-
-
-
- //-----------------------------------------------------------------------------
- // Defines, constants, and global variables
- //-----------------------------------------------------------------------------
- #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
- #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
-
- LPDIRECTINPUT8 g_pDI = NULL;
- LPDIRECTINPUTDEVICE8 g_pJoystick = NULL;
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: WinMain()
- // Desc: Entry point for the application. Since we use a simple dialog for
- // user interaction we don't need to pump messages.
- //-----------------------------------------------------------------------------
- int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
- {
- // Display the main dialog box.
- DialogBox( hInst, MAKEINTRESOURCE(IDD_JOYST_IMM), NULL, MainDlgProc );
-
- return TRUE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: MainDialogProc
- // Desc: Handles dialog messages
- //-----------------------------------------------------------------------------
- INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
- {
- switch( msg )
- {
- case WM_INITDIALOG:
- if( FAILED( InitDirectInput( hDlg ) ) )
- {
- MessageBox( NULL, TEXT("Error Initializing DirectInput"),
- TEXT("DirectInput Sample"), MB_ICONERROR | MB_OK );
- EndDialog( hDlg, 0 );
- }
-
- // Set a timer to go off 30 times a second. At every timer message
- // the input device will be read
- SetTimer( hDlg, 0, 1000 / 30, NULL );
- return TRUE;
-
- case WM_ACTIVATE:
- if( WA_INACTIVE != wParam && g_pJoystick )
- {
- // Make sure the device is acquired, if we are gaining focus.
- g_pJoystick->Acquire();
- }
- return TRUE;
-
- case WM_TIMER:
- // Update the input device every timer message
- if( FAILED( UpdateInputState( hDlg ) ) )
- {
- KillTimer( hDlg, 0 );
- MessageBox( NULL, TEXT("Error Reading Input State. ") \
- TEXT("The sample will now exit."), TEXT("DirectInput Sample"),
- MB_ICONERROR | MB_OK );
- EndDialog( hDlg, TRUE );
- }
- return TRUE;
-
- case WM_COMMAND:
- switch( LOWORD(wParam) )
- {
- case IDCANCEL:
- EndDialog( hDlg, 0 );
- return TRUE;
- }
-
- case WM_DESTROY:
- // Cleanup everything
- KillTimer( hDlg, 0 );
- FreeDirectInput();
- return TRUE;
- }
-
- return FALSE; // Message not handled
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: InitDirectInput()
- // Desc: Initialize the DirectInput variables.
- //-----------------------------------------------------------------------------
- HRESULT InitDirectInput( HWND hDlg )
- {
- HRESULT hr;
-
- // Register with the DirectInput subsystem and get a pointer
- // to a IDirectInput interface we can use.
- // Create a DInput object
- if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
- IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
- return hr;
-
- // Look for a simple joystick we can use for this sample program.
- if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
- EnumJoysticksCallback,
- NULL, DIEDFL_ATTACHEDONLY ) ) )
- return hr;
-
- // Make sure we got a joystick
- if( NULL == g_pJoystick )
- {
- MessageBox( NULL, TEXT("Joystick not found. The sample will now exit."),
- TEXT("DirectInput Sample"),
- MB_ICONERROR | MB_OK );
- EndDialog( hDlg, 0 );
- return S_OK;
- }
-
- // Set the data format to "simple joystick" - a predefined data format
- //
- // A data format specifies which controls on a device we are interested in,
- // and how they should be reported. This tells DInput that we will be
- // passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
- if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) )
- return hr;
-
- // Set the cooperative level to let DInput know how this device should
- // interact with the system and with other DInput applications.
- if( FAILED( hr = g_pJoystick->SetCooperativeLevel( hDlg, DISCL_EXCLUSIVE |
- DISCL_FOREGROUND ) ) )
- return hr;
-
- // Enumerate the joystick objects. The callback function enabled user
- // interface elements for objects that are found, and sets the min/max
- // values property for discovered axes.
- if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback,
- (VOID*)hDlg, DIDFT_ALL ) ) )
- return hr;
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: EnumJoysticksCallback()
- // Desc: Called once for each enumerated joystick. If we find one, create a
- // device interface on it so we can play with it.
- //-----------------------------------------------------------------------------
- BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
- VOID* pContext )
- {
- HRESULT hr;
-
- // Obtain an interface to the enumerated joystick.
- hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
-
- // If it failed, then we can't use this joystick. (Maybe the user unplugged
- // it while we were in the middle of enumerating it.)
- if( FAILED(hr) )
- return DIENUM_CONTINUE;
-
- // Stop enumeration. Note: we're just taking the first joystick we get. You
- // could store all the enumerated joysticks and let the user pick.
- return DIENUM_STOP;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: EnumObjectsCallback()
- // Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
- // joystick. This function enables user interface elements for objects
- // that are found to exist, and scales axes min/max values.
- //-----------------------------------------------------------------------------
- BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
- VOID* pContext )
- {
- HWND hDlg = (HWND)pContext;
-
- static int nSliderCount = 0; // Number of returned slider controls
- static int nPOVCount = 0; // Number of returned POV controls
-
- // For axes that are returned, set the DIPROP_RANGE property for the
- // enumerated axis in order to scale min/max values.
- if( pdidoi->dwType & DIDFT_AXIS )
- {
- DIPROPRANGE diprg;
- diprg.diph.dwSize = sizeof(DIPROPRANGE);
- diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- diprg.diph.dwHow = DIPH_BYID;
- diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
- diprg.lMin = -1000;
- diprg.lMax = +1000;
-
- // Set the range for the axis
- if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
- return DIENUM_STOP;
-
- }
-
-
- // Set the UI to reflect what objects the joystick supports
- if (pdidoi->guidType == GUID_XAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_X_AXIS ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_X_AXIS_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_YAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_Y_AXIS ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_Y_AXIS_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_ZAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_Z_AXIS ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_Z_AXIS_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_RxAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_X_ROT ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_X_ROT_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_RyAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_Y_ROT ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_Y_ROT_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_RzAxis)
- {
- EnableWindow( GetDlgItem( hDlg, IDC_Z_ROT ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_Z_ROT_TEXT ), TRUE );
- }
- if (pdidoi->guidType == GUID_Slider)
- {
- switch( nSliderCount++ )
- {
- case 0 :
- EnableWindow( GetDlgItem( hDlg, IDC_SLIDER0 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_SLIDER0_TEXT ), TRUE );
- break;
-
- case 1 :
- EnableWindow( GetDlgItem( hDlg, IDC_SLIDER1 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_SLIDER1_TEXT ), TRUE );
- break;
- }
- }
- if (pdidoi->guidType == GUID_POV)
- {
- switch( nPOVCount++ )
- {
- case 0 :
- EnableWindow( GetDlgItem( hDlg, IDC_POV0 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_POV0_TEXT ), TRUE );
- break;
-
- case 1 :
- EnableWindow( GetDlgItem( hDlg, IDC_POV1 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_POV1_TEXT ), TRUE );
- break;
-
- case 2 :
- EnableWindow( GetDlgItem( hDlg, IDC_POV2 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_POV2_TEXT ), TRUE );
-
- case 3 :
- EnableWindow( GetDlgItem( hDlg, IDC_POV3 ), TRUE );
- EnableWindow( GetDlgItem( hDlg, IDC_POV3_TEXT ), TRUE );
- }
- }
-
- return DIENUM_CONTINUE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: UpdateInputState()
- // Desc: Get the input device's state and display it.
- //-----------------------------------------------------------------------------
- HRESULT UpdateInputState( HWND hDlg )
- {
- HRESULT hr;
- TCHAR strText[128]; // Device state text
- DIJOYSTATE2 js; // DInput joystick state
- TCHAR* str;
-
- if( NULL == g_pJoystick )
- return S_OK;
-
- // Poll the device to read the current state
- hr = g_pJoystick->Poll();
- if( FAILED(hr) )
- {
- // DInput is telling us that the input stream has been
- // interrupted. We aren't tracking any state between polls, so
- // we don't have any special reset that needs to be done. We
- // just re-acquire and try again.
- hr = g_pJoystick->Acquire();
- while( hr == DIERR_INPUTLOST )
- hr = g_pJoystick->Acquire();
-
- // hr may be DIERR_OTHERAPPHASPRIO or other errors. This
- // may occur when the app is minimized or in the process of
- // switching, so just try again later
- return S_OK;
- }
-
- // Get the input's device state
- if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) )
- return hr; // The device should have been acquired during the Poll()
-
- // Display joystick state to dialog
-
- // Axes
- wsprintf( strText, TEXT("%ld"), js.lX );
- SetWindowText( GetDlgItem( hDlg, IDC_X_AXIS ), strText );
- wsprintf( strText, TEXT("%ld"), js.lY );
- SetWindowText( GetDlgItem( hDlg, IDC_Y_AXIS ), strText );
- wsprintf( strText, TEXT("%ld"), js.lZ );
- SetWindowText( GetDlgItem( hDlg, IDC_Z_AXIS ), strText );
- wsprintf( strText, TEXT("%ld"), js.lRx );
- SetWindowText( GetDlgItem( hDlg, IDC_X_ROT ), strText );
- wsprintf( strText, TEXT("%ld"), js.lRy );
- SetWindowText( GetDlgItem( hDlg, IDC_Y_ROT ), strText );
- wsprintf( strText, TEXT("%ld"), js.lRz );
- SetWindowText( GetDlgItem( hDlg, IDC_Z_ROT ), strText );
-
- // Slider controls
- wsprintf( strText, TEXT("%ld"), js.rglSlider[0] );
- SetWindowText( GetDlgItem( hDlg, IDC_SLIDER0 ), strText );
- wsprintf( strText, TEXT("%ld"), js.rglSlider[1] );
- SetWindowText( GetDlgItem( hDlg, IDC_SLIDER1 ), strText );
-
- // Points of view
- wsprintf( strText, TEXT("%ld"), js.rgdwPOV[0] );
- SetWindowText( GetDlgItem( hDlg, IDC_POV0 ), strText );
- wsprintf( strText, TEXT("%ld"), js.rgdwPOV[1] );
- SetWindowText( GetDlgItem( hDlg, IDC_POV1 ), strText );
- wsprintf( strText, TEXT("%ld"), js.rgdwPOV[2] );
- SetWindowText( GetDlgItem( hDlg, IDC_POV2 ), strText );
- wsprintf( strText, TEXT("%ld"), js.rgdwPOV[3] );
- SetWindowText( GetDlgItem( hDlg, IDC_POV3 ), strText );
-
-
- // Fill up text with which buttons are pressed
- str = strText;
- for( int i = 0; i < 128; i++ )
- {
- if ( js.rgbButtons[i] & 0x80 )
- str += wsprintf( str, TEXT("%02d "), i );
- }
- *str = 0; // Terminate the string
-
- SetWindowText( GetDlgItem( hDlg, IDC_BUTTONS ), strText );
-
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name: FreeDirectInput()
- // Desc: Initialize the DirectInput variables.
- //-----------------------------------------------------------------------------
- VOID FreeDirectInput()
- {
- // Unacquire the device one last time just in case
- // the app tried to exit while the device is still acquired.
- if( g_pJoystick )
- g_pJoystick->Unacquire();
-
- // Release any DirectInput objects.
- SAFE_RELEASE( g_pJoystick );
- SAFE_RELEASE( g_pDI );
- }
-
-
-
-